package com.ppt.convert.service;

import com.alibaba.fastjson.JSON;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.ppt.convert.domain.Result;
import com.ppt.convert.entity.EduFile;
import com.ppt.convert.entity.FileToImage;
import com.ppt.convert.util.FileUtils;
import com.ppt.convert.util.IdGen;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zcx
 * @Title pdf转图片
 * @date 2020年06月23日 10:31
 **/
@Service
public class PdfConvertService {

    @Value("${file.preAbsoluteFolder}")
    private String preAbsoluteFolder;

    @Value("${file.afterAbsoluteFolder}")
    private String afterAbsoluteFolder;

    @Autowired
    private DownLoadService downLoadService;

    @Autowired
    private UploadService uploadService;

    private static final Logger logger = LoggerFactory.getLogger(PdfConvertService.class);

    /**
     *  pdf转化
     * @author zcx
     * @date 2020-07-01 16:13
     * @param dentryId 文件id
     * @param companyId 机构id
     * @param fileUrl 网盘地址
     * @param fileName 文件名
     * @return com.ppt.convert.domain.Result
     */
    public Result pdfConvert(String dentryId, String companyId, String fileUrl, String fileName) {
        //要转换的源文件地址
        String fromPath = afterAbsoluteFolder + "download_cqt" + File.separator + dentryId + File.separator + fileName;
        //要转换的源文件父级目录
        String parrentPath = afterAbsoluteFolder + "download_cqt" + File.separator + dentryId;
        //要转换的路径
        String afterPath = afterAbsoluteFolder + "convert_img" + File.separator + dentryId;
        File file = new File(afterPath);
        if(!file.exists()){
            file.mkdirs(); //创建目录
        }
        logger.info("网盘下载开始---------------------------------------");
        Result result = downLoadService.downLoadFile(parrentPath, fileUrl, dentryId, fileName);
        if (result.getResp_code() == 1) {
            return Result.failed("从网盘下载文件下来失败了----------------");
        }
        logger.info("网盘下载结束---------------------------------------");
        return pdfToImage(parrentPath,fromPath, afterPath, dentryId, companyId, 1f);
    }

    public Result pdfToImage(String parrentPath,String fromPath,
                              String pathAfterPath, String dentryId, String companyId, float times) {
        final Map<String, Object> resultMap = new HashMap<>();
        ComThread.InitSTA();//初始化com的线程
        // PDF页数
        int pageNum = 0;
        // PDF宽、高
        int x, y = 0;
        // PDF控制对象
        Dispatch pdfObject = null;
        // PDF坐标对象
        Dispatch pointxy = null;
        // pdfActiveX PDDoc对象 主要建立PDF对象
        ActiveXComponent app = new ActiveXComponent("AcroExch.PDDoc");
        // pdfActiveX PDF的坐标对象
        ActiveXComponent point = new ActiveXComponent("AcroExch.Point");
        List<String> imageList = new ArrayList<>();
        List<EduFile> eduFileList = new ArrayList<>();
        FileToImage fileToImage = new FileToImage();
        fileToImage.setShareFileId(IdGen.uuid());
        fileToImage.setShareFileName("");
        fileToImage.setClassroomId("");
        fileToImage.setCompanyId(companyId);
        fileToImage.setCreateTime(new Timestamp(System.currentTimeMillis()));
        //文件id
        fileToImage.setShareFileDentryId(dentryId);
        String imageListStr = "";
        try {
            // 得到控制对象
            pdfObject = app.getObject();
            // 得到坐标对象
            pointxy = point.getObject();
            // 打开PDF文件，建立PDF操作的开始
            Dispatch.call(pdfObject, "Open", new Variant(fromPath));
            // 得到当前打开PDF文件的页数
            pageNum = Dispatch.call(pdfObject, "GetNumPages").toInt();
            for (int i = 0; i < pageNum; i++) {
                // 根据页码得到单页PDF
                Dispatch page = Dispatch.call(pdfObject, "AcquirePage",
                        new Variant(i)).toDispatch();
                // 得到PDF单页大小的Point对象
                Dispatch pagePoint = Dispatch.call(page, "GetSize")
                        .toDispatch();
                // 创建PDF位置对象，为拷贝图片到剪贴板做准备
                ActiveXComponent pdfRect = new ActiveXComponent("AcroExch.Rect");
                // 得到单页PDF的宽
                int imgWidth = (int) (Dispatch.get(pagePoint, "x").toInt() * 2 * times);
                // 得到单页PDF的高
                int imgHeight = (int) (Dispatch.get(pagePoint, "y").toInt() * 2 * times);
                // 控制PDF位置对象
                Dispatch pdfRectDoc = pdfRect.getObject();
                // 设置PDF位置对象的值
                Dispatch.put(pdfRectDoc, "Left", new Integer(0));
                Dispatch.put(pdfRectDoc, "Right", new Integer(imgWidth));
                Dispatch.put(pdfRectDoc, "Top", new Integer(0));
                Dispatch.put(pdfRectDoc, "Bottom", new Integer(imgHeight));
                // 将设置好位置的PDF拷贝到Windows剪切板，参数：位置对象,宽起点，高起点，分辨率
                Dispatch.call(page, "CopyToClipboard", new Object[] {
                        pdfRectDoc, 0, 0, 200 * times });
                Image image = getImageFromClipboard();
                BufferedImage tag = new BufferedImage(imgWidth, imgHeight, 8);
                Graphics graphics = tag.getGraphics();
                graphics.drawImage(image, 0, 0, null);
                graphics.dispose();
                String fileName = pathAfterPath + File.separator + dentryId + "_" + (i + 1) + ".jpg";
                File newFile = new File(fileName);
                // 输出图片
                ImageIO.write(tag, "JPEG", newFile);
                String resp = uploadService.upload(FileUtils.fileToMultipartFile(newFile));
                if (resp != "error") {
                    Map<String, Object> respMap = JSON.parseObject(resp, Map.class);
                    String path = respMap.get("fileUrl").toString();
                    EduFile imageFile = new EduFile();
                    //设置图片信息
                    imageFile.setOriginalFilename(fileName);
                    imageFile.setFileName(dentryId + "_" + (i + 1) + ".jpg");
                    imageFile.setExtension("jpg");
                    String[] pathList = path.split("/");
                    String pictureId = pathList[pathList.length - 1];
                    imageFile.setDentryId(pictureId);//文件id
                    imageFile.setFileType(1);//类型为图片
                    imageFile.setPath(path);
                    imageFile.setConvertStatus("1");
                    imageFile.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    imageList.add(pictureId);
                    //入库图片信息
                    eduFileList.add(imageFile);
                }
            }
        } catch (Exception e) {
            return Result.failed("文件转化失败" + e);
        } finally {
            // 关闭PDF
            app.invoke("Close", new Variant[]{});
            ComThread.Release();//关闭com的线程   真正kill进程
            //不管转化失败还是成功都要删除源文件以及转化后的文件
            FileUtils.deleteDirectory(pathAfterPath);
            FileUtils.deleteDirectory(parrentPath);
        }
        imageListStr = String.join(",", imageList);
        fileToImage.setImages(imageListStr);
        resultMap.put("imageListStr", imageListStr);
        resultMap.put("eduFileList", eduFileList);
        resultMap.put("fileToImage", fileToImage);
        return Result.succeed(resultMap, "转化成功");
    }

    public static Image getImageFromClipboard() throws Exception {
        Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable cc = sysc.getContents(null);
        if (cc == null)
            return null;
        else if (cc.isDataFlavorSupported(DataFlavor.imageFlavor))
            return (Image) cc.getTransferData(DataFlavor.imageFlavor);
        return null;
    }
}
